package com.james.service.impl;

import com.alibaba.fastjson.JSON;
import com.james.constants.QueueConstant;
import com.james.domain.Food;
import com.james.domain.User;
import com.james.mapper.FoodMapper;
import com.james.mapper.UserMapper;
import com.james.model.WxMsgModel;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.james.mapper.OrderMapper;
import com.james.domain.Order;
import com.james.service.OrderService;
import org.springframework.transaction.annotation.Transactional;

/**
 * @ClassName: OrderServiceImpl
 * @Author: JamesWang
 * @Date: 2021/4/22 14:19
 * @Description:
 * @Version:1.0
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private FoodMapper foodMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 下订单
     *
     * @param food
     */
    @Transactional
    @Override
    public void doOrder(Food food) {
        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        User user = userMapper.selectById(userId);
        Food orderFood = foodMapper.selectById(food.getFoodId());
        BigDecimal totalMoney = orderFood.getFoodPrice()
                .multiply(new BigDecimal(food.getFoodCount()));

        String orderNum = UUID.randomUUID().toString();
        Order order = Order.builder()
                .orderNum(orderNum)
                .userId(Integer.valueOf(userId))
                .foodId(food.getFoodId())
                .totalMoney(totalMoney)
                .count(food.getFoodCount())
                .orderStatus(1)
                .createTime(new Date()).build();
        orderMapper.insert(order);

        int score = user.getScore() + totalMoney.intValue();
        user.setScore(score);
        userMapper.updateById(user);

        // 发送微信消息
        Map<String, Object> map = new HashMap<>(8);
        map.put("price", totalMoney.toString());
        map.put("foodName", orderFood.getFoodName());
        this.sendWxMsg(userId, map);
    }

    /**
     * 发送微信消息
     *
     * @param userId
     * @param map
     */
    private void sendWxMsg(String userId, Map<String, Object> map) {
        // 构建一个微信消息
        WxMsgModel wxMsgModel = new WxMsgModel();
        wxMsgModel.setUrl("https://www.bilibili.com/");
        wxMsgModel.setToUser("oq9UU6qpsj3BnMUoTeNUO6hJE-zU");
        wxMsgModel.setTopColor("#FF0000");
        wxMsgModel.setTemplateId("MIdnnebcc6MVbqSQ1EJVXy98_402TXcxhXJ2X89s_j0");
        // 组装数据
        HashMap<String, Map<String, String>> data = new HashMap<>(8);
        data.put("time", WxMsgModel.buildMap(LocalDateTime.now().toString(), "#FF0000"));
        data.put("foodName", WxMsgModel.buildMap(map.get("foodName").toString(), "#FF0000"));
        data.put("price", WxMsgModel.buildMap(map.get("price").toString(), "#FF0000"));
        data.put("cancelTime", WxMsgModel.buildMap("30", "#FF0000"));
        wxMsgModel.setData(data);
        // 放入mq中
        rabbitTemplate.convertAndSend(QueueConstant.WX_SMS_EX, QueueConstant.WX_SMS_KEY, JSON.toJSONString(wxMsgModel));
    }

    /**
     * 用户取消订单
     *
     * @param orderId
     */
    @Override
    @Transactional
    public void cancelOrder(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        if (1 != order.getOrderStatus()) {
            throw new RuntimeException("订单已作废");
        }
        order.setOrderStatus(2);
        orderMapper.updateById(order);

        String userId = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        User user = userMapper.selectById(userId);
        int finalScore = user.getScore() - order.getTotalMoney().intValue();
        if (finalScore <= 0) finalScore = 0;
        user.setScore(finalScore);
        userMapper.updateById(user);
    }
}
